package com.quanyan.place.web.api;

import java.util.Date;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.common.utils.DateUtils;
import com.quanyan.orderpay.response.mq.OrderNotifyMsg;
import com.quanyan.orderpay.response.mq.RefundNotifyMsg;
import com.quanyan.orderpay.response.mq.WithdrawTransferNotify;
import com.quanyan.pay.enums.RefundStatusEnum;
import com.quanyan.place.constants.PlaceConstants;
import com.quanyan.place.entity.apireq.ExtractCallBackVo;
import com.quanyan.place.entity.apireq.ReqOrderOperate;
import com.quanyan.place.service.PlaceBizSettleService;
import com.quanyan.place.service.PlacePromoteService;
import com.quanyan.place.wrapper.PlaceOrderServiceWrapper;

/**
 * Created by Kingson.chan on 2016/8/5 0005.
 */
@RestController
@RequestMapping("/api/place/callback/")
public class CallbackController {
    @Autowired
    PlaceOrderServiceWrapper placeOrderServiceWrapper;

    @Autowired
    private PlacePromoteService placePromoteService;

    @Autowired
    PlaceBizSettleService  placeBizSettleService;

    private final static Logger logger = LoggerFactory.getLogger(CallbackController.class);


    /**
     * 支付成功回调
     *
     * */
    @RequestMapping(value="/payCallback", method = RequestMethod.POST)
    public APIResponse<?> openPayType(@RequestBody OrderNotifyMsg orderNotifyMsg)  {
        if(OrderNotifyMsg.RESULT_CODE_USER_PAY_SUCCESS.equals(orderNotifyMsg.getResultCode())){
            ReqOrderOperate reqOrderOperatePaySuccess = new ReqOrderOperate();
            reqOrderOperatePaySuccess.setUid(orderNotifyMsg.getUid());
            reqOrderOperatePaySuccess.setOrderNo(orderNotifyMsg.getOutTradeNo());
            reqOrderOperatePaySuccess.setOperateType(PlaceConstants.ORDER_COMPLETE_OPERATE);
            reqOrderOperatePaySuccess.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);
            reqOrderOperatePaySuccess.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
            reqOrderOperatePaySuccess.setPayTime(new Date(orderNotifyMsg.getPayTime()));
            reqOrderOperatePaySuccess.setPayInfoList(orderNotifyMsg.getPayInfoList());
            reqOrderOperatePaySuccess.setCallBackType(1);//支付完成回调
            logger.info("订单支付成功回调：{}", JSON.toJSONString(reqOrderOperatePaySuccess));
            APIResponse apiResponse =  placeOrderServiceWrapper.orderOperate(reqOrderOperatePaySuccess);
            if(apiResponse.isRet()){
                logger.warn("回调消息:订单支付成功，用户号：{}，订单号：{} ",orderNotifyMsg.getUid(), orderNotifyMsg.getOutTradeNo());
            }
            return apiResponse;
        }
        else if(OrderNotifyMsg.RESULT_CODE_USER_PAY_FAIL.equals(orderNotifyMsg.getResultCode())){
            //支付失败，进行取消订单处理
            ReqOrderOperate reqOrderOperatePayFail = new ReqOrderOperate();
            reqOrderOperatePayFail.setUid(orderNotifyMsg.getUid());
            reqOrderOperatePayFail.setOrderNo(orderNotifyMsg.getOutTradeNo());
            reqOrderOperatePayFail.setOperateType(PlaceConstants.ORDER_CANCEL_OPERATE);
            reqOrderOperatePayFail.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);//admin用户对于取消次数不做限制
            reqOrderOperatePayFail.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
            reqOrderOperatePayFail.setCallBackType(3);//订单关闭
            logger.info("订单进行取消回调：{}", JSON.toJSONString(reqOrderOperatePayFail));
            APIResponse apiResponse = placeOrderServiceWrapper.orderOperate(reqOrderOperatePayFail);
            if(apiResponse.isRet()){
                logger.warn("回调消息:订单支付失败，用户号：{}，订单号：{} ", orderNotifyMsg.getUid(), orderNotifyMsg.getOutTradeNo());
            }
            return apiResponse;
        }
        return APIResponse.returnFail("");

    }

    /**
     * 退款回调
     *
     * */
    @RequestMapping(value="/refundCallback", method = RequestMethod.POST)
    public APIResponse<?> refundCallback(@RequestBody RefundNotifyMsg refundNotifyMsg)  {
        if(RefundStatusEnum.SUCCESS.getId() == refundNotifyMsg.getRefundState()){
            ReqOrderOperate reqOrderOperatePayRefundSuccess = new ReqOrderOperate();
            reqOrderOperatePayRefundSuccess.setUid(refundNotifyMsg.getUid());
            reqOrderOperatePayRefundSuccess.setOrderNo(refundNotifyMsg.getOutTradeNo());
            reqOrderOperatePayRefundSuccess.setRefundOrderNo(refundNotifyMsg.getOutTradeRefundOrderNo());
            reqOrderOperatePayRefundSuccess.setOperateType(PlaceConstants.ORDER_COMPLETE_UNSUBSCRIBE_OPERATE);
            reqOrderOperatePayRefundSuccess.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);
            reqOrderOperatePayRefundSuccess.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
            reqOrderOperatePayRefundSuccess.setExceptionFlag(refundNotifyMsg.getExceptionFlag());
            reqOrderOperatePayRefundSuccess.setCallBackType(2);//申请回调表示
            APIResponse apiResponse = placeOrderServiceWrapper.orderOperate(reqOrderOperatePayRefundSuccess);
            if(apiResponse.isRet()){
                logger.warn("回调消息:订单退款成功，用户号：{}，订单号：{} ", refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
            }
            return apiResponse;
        }
        //其他状态暂时不做处理
        else if(RefundStatusEnum.FAIL.getId() == refundNotifyMsg.getRefundState()){
            logger.warn("回调消息:订单退款失败，用户号：{}，订单号：{} ",refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
        }
        else if (RefundStatusEnum.CHANGE.getId() == refundNotifyMsg.getRefundState()){
            logger.warn("回调消息:订单退款失败,需要人工退款，用户号：{}，订单号：{} ",  refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
        }
        else {
            logger.warn("回调消息:订单退款异常，用户号：{}，订单号：{} 退款状态：{}", refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo(),refundNotifyMsg.getRefundState());
        }
        return APIResponse.returnFail("");
    }


    /**
     * 订单关闭回调
     *
     * */
    @RequestMapping(value="/orderCloseCallback", method = RequestMethod.POST)
    public APIResponse<?> orderCloseCallback(@RequestBody OrderNotifyMsg orderNotifyMsg)  {
        ReqOrderOperate reqOrderOperatePayFail = new ReqOrderOperate();
        reqOrderOperatePayFail.setUid(orderNotifyMsg.getUid());
        reqOrderOperatePayFail.setOrderNo(orderNotifyMsg.getOutTradeNo());
        reqOrderOperatePayFail.setOperateType(PlaceConstants.ORDER_CANCEL_OPERATE);
        reqOrderOperatePayFail.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);//admin用户对于取消次数不做限制
        reqOrderOperatePayFail.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
        reqOrderOperatePayFail.setIsCallBackOrder(PlaceConstants.NO);
        reqOrderOperatePayFail.setCallBackType(3);//订单关闭
        APIResponse apiResponse = placeOrderServiceWrapper.orderOperate(reqOrderOperatePayFail);
        if(apiResponse.isRet()){
            logger.warn("回调消息:订单关闭成功，用户号：{}，订单号：{} ", orderNotifyMsg.getUid(), orderNotifyMsg.getOutTradeNo());
        }
        return apiResponse;
    }

    /**
     * 异常退款回调
     *
     * */
    @RequestMapping(value="/exceptionRefundCallback", method = RequestMethod.POST)
    public APIResponse<?> exceptionRefundCallback(@RequestBody RefundNotifyMsg refundNotifyMsg)  {
        if(RefundStatusEnum.SUCCESS.getId() == refundNotifyMsg.getRefundState()){
            ReqOrderOperate reqOrderOperatePayRefundSuccess = new ReqOrderOperate();
            reqOrderOperatePayRefundSuccess.setUid(refundNotifyMsg.getUid());
            reqOrderOperatePayRefundSuccess.setOrderNo(refundNotifyMsg.getOutTradeNo());
            reqOrderOperatePayRefundSuccess.setOperateType(PlaceConstants.ORDER_CANCEL_TO_UNSUBSCRIBE_OPERATE);
            reqOrderOperatePayRefundSuccess.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);
            reqOrderOperatePayRefundSuccess.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
            reqOrderOperatePayRefundSuccess.setCallBackType(4);//退款中
            APIResponse apiResponse = placeOrderServiceWrapper.orderOperate(reqOrderOperatePayRefundSuccess);
            if(apiResponse.isRet()){
                logger.warn("回调消息:订单异常退款处理成功，用户号：{}，订单号：{} ", refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
            }
            return apiResponse;
        }
        //其他状态暂时不做处理
        else if(RefundStatusEnum.FAIL.getId() == refundNotifyMsg.getRefundState()){
            logger.warn("回调消息:订单异常退款处理失败，用户号：{}，订单号：{} ",refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
        }
        else if (RefundStatusEnum.CHANGE.getId() == refundNotifyMsg.getRefundState()){
            logger.warn("回调消息:订单异常退款处理失败,需要人工退款，用户号：{}，订单号：{} ",  refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo());
        }
        else {
            logger.warn("回调消息:订单异常退款处理异常，用户号：{}，订单号：{} 退款状态：{}", refundNotifyMsg.getUid(), refundNotifyMsg.getOutTradeNo(),refundNotifyMsg.getRefundState());
        }
        return APIResponse.returnFail("");
    }

    /**
     * 支付成功确认回调 （解决内部系统超时）
     *
     * */
    @RequestMapping(value="/payConfirmCallback", method = RequestMethod.POST)
    public APIResponse<?> payConfirmCallback(@RequestBody OrderNotifyMsg orderNotifyMsg)  {
        if(OrderNotifyMsg.RESULT_CODE_USER_PAY_SUCCESS.equals(orderNotifyMsg.getResultCode())){
            ReqOrderOperate reqOrderOperatePaySuccess = new ReqOrderOperate();
            reqOrderOperatePaySuccess.setUid(orderNotifyMsg.getUid());
            reqOrderOperatePaySuccess.setOrderNo(orderNotifyMsg.getOutTradeNo());
            reqOrderOperatePaySuccess.setOrderSystemNo(orderNotifyMsg.getOrderNo());
            reqOrderOperatePaySuccess.setOperateType(PlaceConstants.ORDER_PAY_CONFIRM_OPERATE);
            reqOrderOperatePaySuccess.setUserType(PlaceConstants.ORDER_OPERATE_ADMINUSER);
            reqOrderOperatePaySuccess.setOrderOperateKey(PlaceConstants.ORDER_OPERATE_KEY);
            reqOrderOperatePaySuccess.setPayTime(new Date(orderNotifyMsg.getPayTime()));
            APIResponse apiResponse =  placeOrderServiceWrapper.orderOperate(reqOrderOperatePaySuccess);
            if(apiResponse.isRet()){
                logger.warn("回调消息:订单支付成功，用户号：{}，订单号：{}，订单系统号：{} ",orderNotifyMsg.getUid(), orderNotifyMsg.getOutTradeNo(), orderNotifyMsg.getOrderNo());
            }
            return apiResponse;
        }
        return APIResponse.returnFail("");

    }



    /**
     * 供应商结算提现回调
     * 回调传回付款时间   提现流水号
     */
    @RequestMapping(value="/supplierExtractUrlCallback", method = RequestMethod.POST)
    public APIResponse<?> supplierExtractUrlCallback(@RequestBody WithdrawTransferNotify notifytVo) {
        APIResponse apiResponse=null;
        ExtractCallBackVo eVo = new ExtractCallBackVo();
        if (notifytVo.getTag()) {
            eVo.setExtractNo(notifytVo.getApplyNo());
            eVo.setStatus(2);
            eVo.setPayTime(DateUtils.tranferStringToDate(notifytVo.getCompletedTime()));
             apiResponse = placeOrderServiceWrapper.updateExtractInfoByExtractNo(eVo);
            if (apiResponse.isRet()) {
                logger.warn("回调消息:供应商提现成功，提现流水号：{} ", notifytVo.getApplyNo());
            }
        } else {
            eVo.setExtractNo(notifytVo.getApplyNo());
            eVo.setStatus(3);
            eVo.setPayTime(DateUtils.tranferStringToDate(notifytVo.getCompletedTime()));
             apiResponse = placeOrderServiceWrapper.updateExtractInfoByExtractNo(eVo);
            if (apiResponse.isRet()) {
                logger.warn("回调消息:供应商提现失败，提现流水号：{} ", notifytVo.getApplyNo());
            }
        }
        return apiResponse;
    }

    /**
     * 财务系统打款成功后回调
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/promoteRewardPayCallback", method = RequestMethod.POST)
    @ResponseBody
    public APIResponse<?> promoteRewardPayCallback(@RequestBody @Valid WithdrawTransferNotify notify, BindingResult bindingResult)  {
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        APIResponse apiResponse = placePromoteService.promoteRewardPayCallback(notify);
        return apiResponse;
    }

    /**
     * 自营场馆现金结算转账成功后回调
     * @param
     * @return
     */
    @RequestMapping(value = "/cashForScanTransferCallback", method = RequestMethod.POST)
    @ResponseBody
    public APIResponse<?> cashForScanTransferCallback(@RequestBody  OrderNotifyMsg notify) {
        if (OrderNotifyMsg.RESULT_CODE_USER_PAY_SUCCESS.equals(notify.getResultCode())) {
            placeBizSettleService.cashForScanTransferCallback(notify);
            return APIResponse.returnSuccess("转账成功");
        } else if (OrderNotifyMsg.RESULT_CODE_USER_PAY_FAIL.equals(notify.getResultCode())) {
            return APIResponse.returnFail("转账失败");
        }
        return APIResponse.returnFail("转账失败");
    }

}
